iT邦幫忙

2025 iThome 鐵人賽

DAY 4
0
Modern Web

從 React 學 Next.js:不只要會用,還要真的懂系列 第 4

【Day 4】SSG vs ISR:從純靜態頁面到可自動更新的靜態頁面

  • 分享至 

  • xImage
  •  

今天我們一樣不會直接進入 Next.js 的世界,而是從回顧什麼是 SSR 開始來看 SSG 和 ISR 這兩種網頁渲染模式。
(前提說明:這篇是之前在自己的部落格有分享過的主題,所以內容會跟之前的文章內容差不多)

回顧 SSR

SSR 指的是「伺服器端渲染 (Server-Side Rendering)」,也就是說渲染 HTML 的這件事情是交由伺服器來處理,所以瀏覽器在發送 request 後,得到的 response 會是完整頁面的 HTML 檔案。

SSR 有分舊時代的 SSR 和新時代的 SSR,舊時代的 SSR 就是前面所提到的「發送 request 後,由伺服器回完整頁面的 HTML 及相關的 CSS 給瀏覽器,每次進行互動的動作時,例如:送出表單,都會重新經歷一次這個發送 request,在次取得一份新的 HTML 的動作」。但在新時代的 SSR 中,是「優化了每次做一個操作動作,就要重新發送 request 取得新的 HTML 的部分,這份 HTML 中包含了前端 JavaScript 程式碼,當頁面載入完後,這些 JavaScript 會在瀏覽器端啟動並接管頁面操作邏輯,這個啟動過程叫做 Hydration,從第二次互動開始(例如:點選、輸入、切換頁面)就不需要重新從伺服器取得整頁 HTML,而是由前端程式直接處理互動行為,這使得網站既有良好的初始 SEO 表現,又保有像 SPA 那樣的操作體驗。

新時代的 SSR 雖然解決舊時代的 SSR 每次做一個操作都要重新等待完整的 HTML 回來的缺點,又保持著第一次進入頁面時就可以拿到完整的 HTML 頁面,以維持有助於 SEO 的優點,以及保有 SPA 的操作體驗,但是相對地它對於伺服器造成的負荷也比較大,。

從上述的回顧內容可以了解到新時代的 SSR 因為會在伺服器上渲染出完整的 HTML 才返回給瀏覽器,所以對於 SEO 很有幫助,再加上他又解決了舊時代 SSR 在操作互動上,需要從新發送 request 的這個問題,所以在互動操作上,速度會變得更快,但也因為這樣對於伺服器的負載也變高,這樣對於每個需要 SEO 的使用情境真的都一定會有完全正向的幫助嗎?像是「公司介紹頁」、「產品資訊頁」這類內容變動頻率不高,互動性也不強的頁面,是不是還有其他效能更好的做法可以使用呢?

接下來就讓我們來進入今天的正題:SSG 和 ISR 吧!

什麼是 SSG ?

所謂的 SSG 指的是 「靜態網頁生成 (Static Site Generation)」,簡單來說就是在專案 build 的階段 (執行 build 指令時) 的時候,就預先產生對應的 HTML 頁面,有別於 SSR 這個渲染模式,要在使用者發送 request 後,才在伺服器上產生 HTML 檔案,SSG 是在 build 時就完成 HTML 的渲染,因此這些靜態檔案可以快取在 CDN 上,加快使用者的載入速度,同時也減輕伺服器負擔,在效能上也有明顯優勢,非常適合內容變動頻率低的頁面,例如產品介紹、部落格文章等。

這裡也實際從 run build 後的檔案觀察,產生的檔案有什麼差異。我用 Next.js 建了兩個 /new 的 index 檔案,左邊使用的渲染模式是 SSR ,右邊使用的渲染模式是 SSG。

https://ithelp.ithome.com.tw/upload/images/20250830/201309140khfrMRCCX.png

當 run build 之後,可以看到在 SSR 的模式下,並沒有產生 new 的 HTML 檔案,相反的,在 SSG 模式下,則有產生出一個 new 的 HTML 檔案,這部分就如同前面所提到的一樣,「SSG 與 SSR 不同的地方在於 SSG 在 build 的時候,就會產生 HTML 檔案,不需要在發送 request 時,才透過伺服器產生 HTML 檔案給瀏覽器」。

https://ithelp.ithome.com.tw/upload/images/20250830/20130914qYauCFmqey.png

其實從前面提到的特性應該不難了解到 SSG 的優點是利於維持 SEO ,並且有較好效能,不過由於每次內容有更新,都要重新 build 一次檔案,也就比較不適合資料會頻繁有變動的頁面,因此這種形態的渲染方式,會比較適合大多時候都不會有更新的靜態頁面,例如:部落格、公司介紹頁面。

不過實務上,我們有時還是會遇到一種情況,那就是頁面雖然不需要即時更新,但還是需要定期維護或更新資料。這種情境如果每次都手動重建 SSG,其實既費時又不方便。這時候,就可以考慮另一種渲染模式,那就是 ISR。

帶有 SSG 優點並補強 SSG 缺點的 ISR

ISR 指的是「增量靜態生成 (Incremental Static Regeneration)」。簡單來說的話,就是維持 SSG 在 build 的時候就產生靜態 HTML 檔案的優點,又帶有不需要透過 build 來更新頁面的特點。

當使用者發送 request 去取得 SSG 的頁面時,會去確認這個頁面是否已經過期,如果沒有過期,會透過 response 返回舊的檔案,如果過期,會在背景進行重新生成新靜態檔案的動作,此時若還沒產生好,會先返回舊的檔案,下次再次進入頁面,則可以取得新產生的檔案。這樣帶有靜態頁面特性,及特定時間自動更新產生新靜態頁面的彈性,讓 ISR 很適合一些需要定期更新,但不需要即時更新的頁面,例如:新聞文章頁面、活動頁面。

接下來一樣用範例來看看 ISR 和 SSG 有什麼差異!

在這個範例中,也是使用 Next.js 寫一個使用 ISR 的 /new 的 index 檔案,這裡有使用 revalidate 來讓網頁可以定期地在不重新 build 的情況下,也能更新頁面。
(這裡關於 Next.js 的用法,我們後面才會來仔細了解)

https://ithelp.ithome.com.tw/upload/images/20250830/20130914X2Gnljc7jI.png

這次特別在 getStaticProps 函式裡面加上一個 console.log 來觀察。
除此之外,我們一樣先 run build 觀察一下 build 完後的檔案,可以發現就如同 SSG 的特性一樣,在 build 的時候,也會產生出 HTML。

https://ithelp.ithome.com.tw/upload/images/20250830/20130914HUMY0PVwHS.png

另外也透過 console.log 來觀察「頁面過期時,觸發生成新頁面」的動作。
可以發現到當我們第一次進入頁面時,會先顯示一個時間點 (10:54:11),這時候因為頁面還沒有過期,所以沒有觸發 getStaticProps 這個函式,但是再次進入頁面後,因為頁面過期了,就呼叫了 getStaticProps,並在 vscode 的 terminal 內印出時間 (11:02:26),但可以發現到 terminal 印出的時間,與當下的頁面 (10;54:11) 並不一致,那是因為新的頁面並沒有馬上產生好,所以會先使用舊的頁面,等到再次進入這個網址,才會使用最新的頁面,意即再次進入這個網址才會是顯示 11:02:26 的頁面。

https://i.imgur.com/K0RpGJ0.gif

如果再進一步觀察 Response Headers,也可以發現到會有 s-maxage=60 和 stale-while-revalidate=31535940 的設定值內容,這些設定值明確指出了這個頁面在快取中的有效期限,以及重新驗證期間的行為。

https://ithelp.ithome.com.tw/upload/images/20250830/20130914FDcyrrVf8S.png

SSG 和 ISR 的優點和缺點

最後再來回顧一下前面說提到的 SSG 及 ISR 的特點,也思考一下它們各自的優缺點吧!

SSG 有別於 SSR,會在 build 的時候就產生完整的 HTML 靜態檔案,而不需要在發送 request 後,才透過伺服器產生靜態檔案,所以如果 SSG 的頁面需要更新,就需要重新再 build 一次,這樣的特性使得 SSG 在內容更新的靈活度上比較差,也因此會比較適合使用在大多數時間都不太需要更新內容的頁面。

ISR 則是一種 SSG 模式的延伸,它一樣是在 build 的時候,就會產生完整的 HTML 靜態檔案,但是不需要每次都手動 build 一次,而是可以進行一些設定,來決定頁面的過期時間,當頁面過期時,再重新在背景產生新的靜態檔案。因為這樣的特性使得 ISR 適合使用在內容雖然需要更新,但不需要頻繁或即時更新的頁面上。

https://ithelp.ithome.com.tw/upload/images/20250830/20130914BOHG2lblka.png

雖然到今天為止我們還沒正式深入認識 Next.js 這位男主角,但因為這些渲染模式正是它所主打的核心功能,所以這幾天就先從理解各種渲染方式開始。明天會接著來看看一個和 SSR 有點像,又不太一樣的元件類型,也就是 React Server Component。


上一篇
【Day 3】CSR vs SSR:瀏覽器渲染到伺服器渲染
下一篇
【Day 5】一樣不一樣? React Server Component (RSC) vs SSR
系列文
從 React 學 Next.js:不只要會用,還要真的懂11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言